﻿# -*- coding: utf-8 -*-
from Tkinter import *
from time import sleep
from HttpClient import HttpClient
import json,io
from multiprocessing import Process
import multiprocessing
from PIL import Image, ImageTk
class WebQQ(HttpClient):
    def __init__(self):
        self.__cookie = ""
        self.__ptwebqq = ""
        self.__vfwebqq = ""
        self.__hash = ""
        self.__uin = ""
        self.__root = ""
        self.__psessionid = ""
        self.queue = multiprocessing.Queue()

    #获取二维码
    def __ptqrshow(self):
        img = self.Get(url="https://ssl.ptlogin2.qq.com/ptqrshow?appid=501004106&e=0&l=M&s=5&d=72&v=4&t=0.4139144900254905")
        if(img!=None):
            data_stream = io.BytesIO(img)
            imgfile = Image.open(data_stream)
            p = Process(target=self._run_proc, args=(imgfile,))
            p.start()
            print(u"二维码下载完毕，请尽快扫描...")
            return True
        else:
            print(u"二维码下载失败")
            return False

    #检测扫码状态，登录进度
    def __ptqrlogin(self):
        res = self.Get("https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1"+
                       "&login2qq=1&aid=501004106&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10"+
                       "&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-136435"+
                       "&mibao_css=m_webqq&t=undefined&g=1&js_type=0&js_ver=10139&login_sig=&pt_randsalt=0",
                       "https://ui.ptlogin2.qq.com/cgi-bin/login")
        if(res!=None):
            result = res.find("登录成功")
            if(result==-1):
                sleep(1)

                return self.__ptqrlogin()
            elif(result!=-1):
                res = res.decode("UTF-8")
                return self.__check_sig(res[res.find("http"):res.find(u"','0','登录成功！'")].encode())
            else:
                return False
        else:
            return False
    #获得ptwebqq  cookie
    def __check_sig(self,url):
        res = self.Get(url=url,refer="https://ui.ptlogin2.qq.com/cgi-bin/login")
        if(res!=None):
            self.__ptwebqq = self.getCookie("ptwebqq")
            self.__getvfwebqq()
            return self.__login2()
        else:
            return False
    #获得vfwebqq  cookie
    def __getvfwebqq(self):
        res = self.Get(url="http://s.web2.qq.com/api/getvfwebqq?ptwebqq="+self.__ptwebqq+
                       "&clientid=53999199&psessionid=&t=1446710396202",
                     refer="http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1")
        if(res!=None):
            jsn = json.loads(res)
            self.__vfwebqq = jsn["result"]["vfwebqq"]
    #登录 获取uin psessionid
    def __login2(self):
        data = "r=%7B%22ptwebqq%22%3A%22"+self.__ptwebqq+"%22%2C%22clientid%22%3A53999199%2C%22psessionid%22%3A%22%22%2C%22status%22%3A%22online%22%7D"

        res = self.Post(url = "http://d1.web2.qq.com/channel/login2",
                        data = data.encode(encoding="utf8"),
                        refer = "http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=2")
        if(res==None):
            return False
        jsn = json.loads(res)
        if(jsn["retcode"]==0):
            self.__uin = jsn["result"]["uin"]
            self.__psessionid = jsn["result"]["psessionid"]
            self.__hash = self.__friendsHash(self.__uin,self.__ptwebqq)
            self.__get_user_friends()
            return True
        else:
            return False
    #好友的hash  参考HexBlog  
    def __friendsHash(self,uin,pt):
        N=[0 for x in range(4)]
        V=[0 for x in range(4)]
        U=[0 for x in range(8)]
        #    字符串转换为字符数组
        k=pt.encode(encoding="UTF8")
        n=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]
        for x in range(len(k)):
            N[x%4]^=ord(k[x])
        x=int(uin)
        V[0] = x >> 24 & 255 ^ 69;
        V[1] = x >> 16 & 255 ^ 67;
        V[2] = x >> 8 & 255 ^ 79;
        V[3] = x & 255 ^ 75;        
        for x in range(8):
            U[x]=(x%2==0) and N[x>>1] or V[x>>1]
        result=""
        for x in U:
            result+=n[x>>4&15]
            result+=n[x&15]
        return result
    #获取好友列表
    def __get_user_friends(self):
        data="r=%7B%22vfwebqq%22%3A%22"+self.__vfwebqq+"%22%2C%22hash%22%3A%22"+self.__hash+"%22%7D"
        res=self.Post(url="http://s.web2.qq.com/api/get_user_friends2",
                       data=data.encode(encoding="utf8"),
                         refer="http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1")
        if(res!=None):
            #    记录好友列表
            jsn=json.loads(res)
            if(jsn["retcode"]==0):
                #    正确返回列表后
                for x in jsn["result"]["marknames"]:
                    print (x["markname"])
    #心跳包并接收消息，现在不能用了
    #def __poll(self):
    #    data="r=%7B%22ptwebqq%22%3A%22"+self.__ptwebqq+"%22%2C%22clientid%22%3A53999199%2C%22psessionid%22%3A%22"+self.__psessionid +"%22%2C%22key%22%3A%22%22%7D"
    #    res=self.Post(url="http://d1.web2.qq.com/channel/poll2",
    #                  data=data.encode(encoding="utf8"),
    #                  refer="http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2")
    #    if(res!=None):
    #        print res

    def __check_queue(self):
        try:
            out = self.queue.get_nowait()
            if out == 'stop':
                self.__do_stop()
                return
            # Could check for other commands here, too
        except :
            pass
        self.__root.after(100, self.__check_queue)

    def __stop(self):
        self.queue.put('stop')

    def __do_stop(self):
        self.__root.destroy()

    def _run_proc(self,imgfile):
        self.__root = Tk()
        self.__root.title(u"二维码")
        result = ImageTk.PhotoImage(imgfile)
        label = Label(self.__root, image=result)
        label.pack()
        self.__root.after(100, self.__check_queue)
        self.__root.mainloop()
    def run(self):
        if(self.__ptqrshow()):
            if(self.__ptqrlogin()):
                print(u"登录成功")
                self.__stop()

if  __name__ =="__main__":
    qq=WebQQ()
    qq.run()